import datetime

from django.db.models import Count
from rest_framework import serializers

from jqdelivery.models import (
    UserDeliveryOrder,
    UserDeliveryOrderGoods,
    UserExpress,
    UserExpressInfo,
)
from jqdelivery.serializers import (
    UserDeliveryOrderGoodsSerializer,
    UserExpressInfoSerializer,
)
from jqgame.basegame import GameType
from jqgame.utils import get_game_data, get_game_name
from jqpackage.models import UserPackageGoods
from warehouse.models import JuqiGood
from warehouse.serializers import JuqiGoodSerializer
from wxuser.models import (
    Users,
    UserOrder,
    UserRefinedOrderGoods,
    UserRefinedOrder,
)
from wxuser.serializers import UserSerializer
from .models import Finance, GameRule, JuqiAdmin, UserWithdraw


class JuqiAdminSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = JuqiAdmin
        fields = "__all__"


class UserWithdrawSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserWithdraw
        fields = "__all__"


class UserOrderRefinedSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserRefinedOrder
        fields = "__all__"


class UserOrderRefinedGoodsSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = UserRefinedOrderGoods
        fields = "__all__"


class UserPackageDetailedSerializer(serializers.ModelSerializer):
    good = serializers.SerializerMethodField()
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_good(self, obj):
        uuid = obj.good_uuid
        return JuqiGoodSerializer(
            JuqiGood.objects.filter(deleted=False).filter(uuid=uuid).first()
        ).data

    class Meta:
        model = UserPackageGoods
        fields = "__all__"


class UserPackagesGameLevelNameSerializer(serializers.Serializer):
    title = serializers.StringRelatedField()


class UserExpenseRecordSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    game = serializers.SerializerMethodField()

    game_type_name = serializers.SerializerMethodField()

    sum_price = serializers.SerializerMethodField()
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_user(self, obj):
        user_uuid = obj.user_uuid
        user = Users.objects.filter(uuid=user_uuid).first()
        if user is None:
            return None

        return UserSerializer(user).data

    def get_game(self, obj):
        game_uuid = obj.game_uuid
        if game_uuid is None:
            return None
        game_type = obj.game_type
        if game_type is None:
            return None
        if not isinstance(game_type, int):
            game_type = int(game_type)

        return get_game_data(game_uuid, game_type)

    def get_game_type_name(self, obj):
        game_type = obj.game_type
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))

    def get_sum_price(self, obj):
        num = obj.num
        price = obj.price

        if num is None or price is None:
            return 0

        return int(num) * int(price)

    class Meta:
        model = UserOrder
        fields = "__all__"


class UserExpenseRecordGoodsSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    display_url = serializers.CharField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    recovery_price = serializers.IntegerField(read_only=True)
    sum_count = serializers.IntegerField(read_only=True)
    game_type = serializers.CharField(read_only=True)
    good_level_title = serializers.CharField(read_only=True)
    order_num = serializers.IntegerField(read_only=True)


class UserRaffleRecordSerializer(serializers.ModelSerializer):
    user = serializers.SerializerMethodField()
    game = serializers.SerializerMethodField()

    game_type_name = serializers.SerializerMethodField()

    sum_price = serializers.SerializerMethodField()
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_user(self, obj):
        user_uuid = obj.user_uuid
        user = Users.objects.filter(uuid=user_uuid).first()
        if user is None:
            return None

        return UserSerializer(user).data

    def get_game(self, obj):
        game_uuid = obj.game_uuid
        if game_uuid is None:
            return None
        game_type = obj.game_type
        if game_type is None:
            return None
        if not isinstance(game_type, int):
            game_type = int(game_type)

        return get_game_data(game_uuid, game_type)

    def get_game_type_name(self, obj):
        game_type = obj.game_type
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))

    def get_sum_price(self, obj):
        num = obj.num
        price = obj.price

        if num is None or price is None:
            return 0

        return int(num) * int(price)

    class Meta:
        model = UserOrder
        fields = "__all__"


class UserRaffleRecordGoodsSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    display_url = serializers.CharField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    recovery_price = serializers.IntegerField(read_only=True)
    sum_count = serializers.IntegerField(read_only=True)
    game_type = serializers.CharField(read_only=True)
    good_level_title = serializers.CharField(read_only=True)
    order_num = serializers.IntegerField(read_only=True)


class UserProfitSumSerializer(serializers.Serializer):
    user_cost = serializers.IntegerField(read_only=True)
    user_score = serializers.IntegerField(read_only=True)
    user_package_amount = serializers.IntegerField(read_only=True)
    wx_recharge = serializers.IntegerField(read_only=True)
    admin_recharge = serializers.IntegerField(read_only=True)
    whole_recharge = serializers.IntegerField(read_only=True)
    whole_withdraw = serializers.IntegerField(read_only=True)
    whole_shipper_cost = serializers.IntegerField(read_only=True)
    wuxianshang_raffle_income = serializers.IntegerField(read_only=True)
    wuxianshang_raffle_cost = serializers.IntegerField(read_only=True)
    quanjushang_raffle_income = serializers.IntegerField(read_only=True)
    quanjushang_raffle_cost = serializers.IntegerField(read_only=True)
    yifanshang_raffle_income = serializers.IntegerField(read_only=True)
    yifanshang_raffle_cost = serializers.IntegerField(read_only=True)
    hunjing_recharge_raffle_cost = serializers.IntegerField(read_only=True)
    score_recharge_raffle_cost = serializers.IntegerField(read_only=True)
    whole_raffle_income = serializers.IntegerField(read_only=True)
    whole_raffle_cost = serializers.IntegerField(read_only=True)
    whole_raffle_profit = serializers.IntegerField(read_only=True)


class UserProfitDaySerializer(serializers.Serializer):
    date = serializers.DateTimeField(format="%Y-%m-%d")
    user_id = serializers.UUIDField(read_only=True)
    user_name = serializers.CharField(read_only=True)
    user_head_url = serializers.CharField(read_only=True)
    whole_shipper_cost = serializers.IntegerField(read_only=True)
    whole_packages_cost = serializers.IntegerField(read_only=True)
    wx_recharge = serializers.IntegerField(read_only=True)
    admin_recharge = serializers.IntegerField(read_only=True)
    whole_recharge = serializers.IntegerField(read_only=True)
    whole_withdraw = serializers.IntegerField(read_only=True)
    wuxianshang_raffle_income = serializers.IntegerField(read_only=True)
    wuxianshang_raffle_cost = serializers.IntegerField(read_only=True)
    quanjushang_raffle_income = serializers.IntegerField(read_only=True)
    quanjushang_raffle_cost = serializers.IntegerField(read_only=True)
    yifanshang_raffle_income = serializers.IntegerField(read_only=True)
    yifanshang_raffle_cost = serializers.IntegerField(read_only=True)
    hunjing_recharge_raffle_cost = serializers.IntegerField(read_only=True)
    score_recharge_raffle_cost = serializers.IntegerField(read_only=True)
    whole_raffle_income = serializers.IntegerField(read_only=True)
    whole_raffle_cost = serializers.IntegerField(read_only=True)
    whole_raffle_profit = serializers.IntegerField(read_only=True)


class UserRankRechargeSerializer(serializers.Serializer):
    user = serializers.SerializerMethodField()
    user_uuid = serializers.UUIDField(read_only=True)
    whole_recharge = serializers.IntegerField(read_only=True)

    def get_user(self, obj):
        return UserSerializer(
            Users.objects.filter(uuid=obj.get("user_uuid")).first()
        ).data


class UserRankConsumptionSerializer(serializers.Serializer):
    user = serializers.SerializerMethodField()
    user_uuid = serializers.UUIDField(read_only=True)
    whole_raffle_income = serializers.IntegerField(read_only=True)

    def get_user(self, obj):
        return UserSerializer(
            Users.objects.filter(uuid=obj.get("user_uuid")).first()
        ).data


class UserRankProfitSerializer(serializers.Serializer):
    user = serializers.SerializerMethodField()
    user_uuid = serializers.UUIDField(read_only=True)
    whole_raffle_profit = serializers.IntegerField(read_only=True)

    def get_user(self, obj):
        return UserSerializer(
            Users.objects.filter(uuid=obj.get("user_uuid")).first()
        ).data


class UserRecordRechargeSerializer(serializers.Serializer):
    name = serializers.CharField(read_only=True)
    uid = serializers.IntegerField(read_only=True)
    total_fee = serializers.IntegerField(read_only=True)
    type = serializers.IntegerField(read_only=True)
    out_trade_no = serializers.CharField(read_only=True)
    date = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    head_url = serializers.CharField(read_only=True)
    manager = serializers.SerializerMethodField()

    def get_manager(self, obj):
        _admin_uuid = obj.get("admin_uuid")
        if _admin_uuid is None:
            return None
        return (
            JuqiAdmin.objects.filter(deleted=False)
            .filter(uuid=_admin_uuid)
            .first()
            .user
        )


class UserRecordRefinedSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    uuid = serializers.UUIDField(read_only=True)
    name = serializers.CharField(read_only=True)
    uid = serializers.IntegerField(read_only=True)
    head_url = serializers.CharField(read_only=True)
    orderid = serializers.CharField(read_only=True)
    sale_count = serializers.IntegerField(read_only=True)
    sale_money = serializers.IntegerField(read_only=True)
    date = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)


class UserRecordRefinedGoodsSerializer(serializers.Serializer):
    sum_count = serializers.IntegerField(read_only=True)
    good_uuid = serializers.UUIDField()
    good = serializers.SerializerMethodField()

    def get_good(self, obj):
        uuid = obj.get("good_uuid")
        if uuid is None:
            return None
        return JuqiGoodSerializer(
            JuqiGood.objects.filter(deleted=False).filter(uuid=uuid).first()
        ).data


class UserRecordWithdrawSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(read_only=True)
    uid = serializers.IntegerField(read_only=True)
    date = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    withdraw_money = serializers.IntegerField(read_only=True)
    head_url = serializers.CharField(read_only=True)
    manager = serializers.CharField(read_only=True)


class UserRecordScoreSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(read_only=True)
    uid = serializers.IntegerField(read_only=True)
    date = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    score = serializers.IntegerField(read_only=True)
    new_score = serializers.IntegerField(read_only=True)
    detail = serializers.CharField(read_only=True)
    head_url = serializers.CharField(read_only=True)
    manager = serializers.CharField(read_only=True)


class UserRecordPurchaseGoodsSerializer(serializers.Serializer):
    uid = serializers.IntegerField(read_only=True)
    user_uuid = serializers.UUIDField(read_only=True)
    user_name = serializers.StringRelatedField(read_only=True)
    user_head_url = serializers.StringRelatedField(read_only=True)
    game_type = serializers.IntegerField(read_only=True)
    game_type_name = serializers.SerializerMethodField()
    game_uuid = serializers.UUIDField(read_only=True)
    game_name = serializers.StringRelatedField(read_only=True)
    game_cover_url = serializers.StringRelatedField(read_only=True)
    game_box_num = serializers.IntegerField(read_only=True)
    game_price = serializers.IntegerField(read_only=True)
    price = serializers.IntegerField(read_only=True)
    num = serializers.IntegerField(read_only=True)
    good_uuid = serializers.UUIDField(read_only=True)
    good_name = serializers.StringRelatedField(read_only=True)
    good_display_url = serializers.StringRelatedField(read_only=True)
    good_price = serializers.IntegerField(read_only=True)
    good_recovery_price = serializers.IntegerField(read_only=True)
    good_level_name = serializers.StringRelatedField(read_only=True)
    date = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_game_type_name(self, obj):
        game_type = obj.get("game_type")
        if game_type is None:
            return None
        return get_game_name(GameType(game_type))


class UserRecordPersonalDetailsSerializer(serializers.Serializer):
    uid = serializers.IntegerField(read_only=True)
    user = serializers.SerializerMethodField()
    coupon_money = serializers.SerializerMethodField()
    raffle_income = serializers.IntegerField(read_only=True)
    raffle_cost = serializers.IntegerField(read_only=True)
    raffle_profit = serializers.IntegerField(read_only=True)

    def get_coupon_money(self, obj):
        # todo 优惠券 后期添加
        return 0

    def get_user(self, obj):
        return UserSerializer(
            Users.objects.filter(uuid=obj.get("user_uuid")).first()
        ).data


def fill_UserWithdraw(l):
    def _fill_single(userWithdraw: UserWithdraw):
        user = (
            Users.objects.filter(uuid=userWithdraw.user_uuid)
            .filter(deleted=False)
            .first()
        )

        d = {"user": {"": ""}}
        return d

    res = []
    for uw in l:
        res.append(_fill_single(uw))

    return res


class FinanceSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = Finance
        fields = "__all__"


class FinanceMonthSerializer(serializers.Serializer):
    date = serializers.DateTimeField(format="%Y-%m")
    raffle_income = serializers.IntegerField()
    raffle_cost = serializers.IntegerField()
    raffle_profit = serializers.IntegerField()
    statement_date = serializers.SerializerMethodField()

    def get_statement_date(self, obj):
        _date: datetime.datetime = obj.get("date")

        _month = _date.month + 1
        _year = _date.year if _month <= 12 else _date.year + 1
        _month = 1 if _month > 12 else _month
        _day = _date.day
        _hour = _date.hour

        _date = datetime.datetime(
            _year,
            _month,
            _day,
            _hour,
            _date.minute,
            _date.second,
        )

        _date = _date - datetime.timedelta(seconds=1)

        now = datetime.datetime.now()
        if _date > now:
            _date = now
        return _date.strftime("%Y-%m-%d %H:%M:%S")


class FinanceDaySerializer(serializers.Serializer):
    date = serializers.DateTimeField(format="%Y-%m-%d")
    raffle_income = serializers.IntegerField()
    raffle_cost = serializers.IntegerField()
    raffle_profit = serializers.IntegerField()
    statement_date = serializers.SerializerMethodField()

    def get_statement_date(self, obj):
        _date: datetime.datetime = obj.get("date")

        _year = _date.year
        _month = _date.month
        _day = _date.day
        _hour = _date.hour

        _date = datetime.datetime(
            _year,
            _month,
            _day,
            _hour,
            _date.minute,
            _date.second,
        )
        one_seconds = datetime.timedelta(seconds=1)
        one_day = datetime.timedelta(days=1)
        _date = _date + one_day - one_seconds
        now = datetime.datetime.now()

        if _date > now:
            _date = now

        return _date.strftime("%Y-%m-%d %H:%M:%S")


class UserDeliveryOrderSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    delivery_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    pay_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    receive_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    user_express = serializers.SerializerMethodField(read_only=False)
    user = serializers.SerializerMethodField()

    def get_user(self, obj):
        if obj.user_uuid is None:
            return None

        return UserSerializer(Users.objects.filter(uuid=obj.user_uuid).first()).data

    def get_user_express(self, obj):
        if obj.user_express_info_uuid is None:
            return None

        user_express_info = (
            UserExpressInfo.objects.filter(deleted=False)
            .filter(uuid=obj.user_express_info_uuid)
            .first()
        )
        user_express_info_data = None
        if user_express_info is not None:
            user_express_info_data = UserExpressInfoSerializer(user_express_info).data
        return user_express_info_data

    class Meta:
        model = UserDeliveryOrder
        fields = "__all__"


class UserDeliveryOrderDetailedSerializer(serializers.ModelSerializer):
    goods = serializers.SerializerMethodField(read_only=False)
    user = serializers.SerializerMethodField()
    delivery_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    pay_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)
    receive_datetime = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_user(self, obj):
        if obj.user_uuid is None:
            return None

        return UserSerializer(Users.objects.filter(uuid=obj.user_uuid).first()).data

    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    def get_goods(self, obj):
        _query_set = UserDeliveryOrderGoods.objects.filter(deleted=False).filter(
            delivery_order_uuid=obj.uuid
        )
        _query_set = _query_set.values("good_uuid").annotate(sum_count=Count("uuid"))
        _query_set = _query_set.values("good_uuid", "sum_count")
        _query_set = _query_set.all()
        _list = []

        for delivery_goods in _query_set:
            _delivery_goods = UserDeliveryOrderDetailedGoodsSerializer(
                delivery_goods
            ).data
            _list.append(_delivery_goods)

        return _list

    class Meta:
        model = UserDeliveryOrder
        fields = "__all__"


class UserDeliveryOrderDetailedGoodsSerializer(serializers.Serializer):
    sum_count = serializers.IntegerField(read_only=True)
    good_uuid = serializers.UUIDField()
    good = serializers.SerializerMethodField()

    def get_good(self, obj):
        uuid = obj.get("good_uuid")
        if uuid is None:
            return None
        return JuqiGoodSerializer(
            JuqiGood.objects.filter(deleted=False).filter(uuid=uuid).first()
        ).data


class GameRuleSerializer(serializers.ModelSerializer):
    createdAt = serializers.DateTimeField("%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = GameRule
        fields = "__all__"


class GameRuleOptionSerializer(serializers.Serializer):
    label = serializers.StringRelatedField()
    value = serializers.UUIDField()


class GameRuleRequestBodySerializer(serializers.Serializer):
    key = serializers.CharField()

    body = serializers.CharField()

    type = serializers.IntegerField()


class HomeFinSerializer(serializers.Serializer):
    whole_recharge = serializers.IntegerField(read_only=True)
    whole_raffle_income = serializers.IntegerField(read_only=True)
    whole_raffle_cost = serializers.IntegerField(read_only=True)
    whole_raffle_profit = serializers.IntegerField(read_only=True)


class HomeUserSerializer(serializers.Serializer):
    sum_stored_money = serializers.IntegerField(read_only=True)
    sum_hunjing = serializers.IntegerField(read_only=True)
    sum_score = serializers.IntegerField(read_only=True)
    sum_package_amount = serializers.IntegerField(read_only=True)
